///////////////////////////////////////////////////////////////////////////////
//$Date: 2008/05/30 00:57:53 $
//$RCSfile: mgt_usrclk_source_pll.ejava,v $
//$Revision: 1.1.2.1 $
///////////////////////////////////////////////////////////////////////////////
//   __  __ 
//  /   /\/   / 
// /__/  \   /    Vendor: Xilinx 
// \   \   \/     Version : 1.5
//  \   \         Application : RocketIO GTX Wizard 
//  /   /         Filename : mgt_usrclk_source_pll.v
// /__/   /\      Timestamp : 02/08/2005 09:12:43
// \   \  /  \ 
//  \__\/\__\ 
//
//
// Module MGT_USRCLK_SOURCE (for use with GTX Transceivers)
// Generated by Xilinx RocketIO GTX Wizard

`timescale 1ns / 1ps

//***********************************Entity Declaration*******************************
module MGT_USRCLK_SOURCE_PLL #
(
    parameter   MULT            =   2,
    parameter   DIVIDE          =   2,
    parameter   CLK_PERIOD      =   16.0,
    parameter   OUT0_DIVIDE     =   2,
    parameter   OUT1_DIVIDE     =   2,
    parameter   OUT2_DIVIDE     =   2,
    parameter   OUT3_DIVIDE     =   2, 
    parameter   SIMULATION_P    =   1, 
    parameter   LOCK_WAIT_COUNT =   16'b1000001000110101    
)
(
    CLK0_OUT,
    CLK1_OUT,
    CLK2_OUT,
    CLK3_OUT,
    CLK_IN,
    PLL_LOCKED_OUT,
    PLL_RESET_IN
);

// synthesis attribute X_CORE_INFO of MGT_USRCLK_SOURCE_PLL is "gtxwizard_v1_5, Coregen v10.1_ip3";

`define DLY #1


//*********************************** Port Declaration *******************************

    output          CLK0_OUT;
    output          CLK1_OUT;
    output          CLK2_OUT;
    output          CLK3_OUT;
    input           CLK_IN;
    output          PLL_LOCKED_OUT;
    input           PLL_RESET_IN;

//*********************************Wire Declarations**********************************

    wire    [15:0]  tied_to_ground_vec_i;
    wire            tied_to_ground_i;
    wire            clkout0_i;
    wire            clkout1_i;
    wire            clkout2_i;
    wire            clkout3_i;
    wire            clkfbout_i;
    wire            pll_lk_out;

//*********************************Register Declarations**********************************  

    reg     [15:0]  lock_wait_counter; 
    reg             pll_locked_out_r;
    reg             time_elapsed;    

//*********************************** Beginning of Code *******************************

    //  Static signal Assigments    
    assign tied_to_ground_i             = 1'b0;
    assign tied_to_ground_vec_i         = 16'h0000;

    // Instantiate a DCM module to divide the reference clock. Uses internal feedback
    // for improved jitter performance, and to avoid consuming an additional BUFG
    PLL_ADV #
    (
         .CLKFBOUT_MULT     (MULT),
         .DIVCLK_DIVIDE     (DIVIDE),
         .CLKFBOUT_PHASE    (0),
         
         .CLKIN1_PERIOD     (CLK_PERIOD),
         .CLKIN2_PERIOD     (10),   //Not used
         
         .CLKOUT0_DIVIDE    (OUT0_DIVIDE),
         .CLKOUT0_PHASE     (0),
         
         .CLKOUT1_DIVIDE    (OUT1_DIVIDE),
         .CLKOUT1_PHASE     (0),

         .CLKOUT2_DIVIDE    (OUT2_DIVIDE),
         .CLKOUT2_PHASE     (0),
         
         .CLKOUT3_DIVIDE    (OUT3_DIVIDE),
         .CLKOUT3_PHASE     (0)        
    )
    pll_adv_i   
    (
         .CLKIN1            (CLK_IN),
         .CLKIN2            (1'b0),
         .CLKINSEL          (1'b1),
         .CLKFBIN           (clkfbout_i),
         .CLKOUT0           (clkout0_i),
         .CLKOUT1           (clkout1_i),
         .CLKOUT2           (clkout2_i),
         .CLKOUT3           (clkout3_i),
         .CLKOUT4           (),
         .CLKOUT5           (),
         .CLKFBOUT          (clkfbout_i),
         .CLKFBDCM          (),
         .CLKOUTDCM0        (),
         .CLKOUTDCM1        (),
         .CLKOUTDCM2        (),
         .CLKOUTDCM3        (),
         .CLKOUTDCM4        (),
         .CLKOUTDCM5        (),
         .DO                (),
         .DRDY              (),
         .DADDR             (5'd0),
         .DCLK              (1'b0),
         .DEN               (1'b0),
         .DI                (16'd0),
         .DWE               (1'b0),
         .REL               (1'b0),
         .LOCKED            (pll_lk_out),
         .RST               (PLL_RESET_IN)
    );
    
    BUFG clkout0_bufg_i  
    (
        .O              (CLK0_OUT), 
        .I              (clkout0_i)
    ); 


    BUFG clkout1_bufg_i
    (
        .O              (CLK1_OUT),
        .I              (clkout1_i)
    );


    BUFG clkout2_bufg_i 
    (
        .O              (CLK2_OUT),
        .I              (clkout2_i)
    );
    
    
    BUFG clkout3_bufg_i
    (
        .O              (CLK3_OUT),
        .I              (clkout3_i)
    );    

    generate
    if (SIMULATION_P == 1) 
    begin : lockwait_count
    
    // lock not valid until 100us after PLL is released from reset
    always@(posedge CLK_IN or posedge PLL_RESET_IN) 
    begin
        if (PLL_RESET_IN) begin
            lock_wait_counter <= 16'b0000000000000000; 
            pll_locked_out_r <= 1'b0;
            time_elapsed <= 1'b0;
        end
        else begin
            if (lock_wait_counter == LOCK_WAIT_COUNT | time_elapsed) begin
                pll_locked_out_r <= pll_lk_out; 
                time_elapsed <= 1'b1;
            end
            else 
                lock_wait_counter <= lock_wait_counter + 1; 
        end
    end
    
    assign PLL_LOCKED_OUT = pll_locked_out_r;
    
    end //  End SIMULATION_P=1 generate section
    else 
    begin: no_lockwait_count
    
    assign PLL_LOCKED_OUT = pll_lk_out;
    
    end
    endgenerate //  End generate for SIMULATION_P    

endmodule

